var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
file.append("stylish.rdf");
var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
if (!file.exists()) {
//either this is the first run or the user deleted his file (the bastard)
//read the default file's contents (courtesy Torisugari <http://forums.mozillazine.org/viewtopic.php?p=921150#921150>)
var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"].getService(Components.interfaces.nsIScriptableInputStream);
var channel = ioService.newChannel("chrome://stylish/content/stylish-default.rdf", null, null);
var input = channel.open();
scriptableStream.init(input);
var data = scriptableStream.read(input.available());
scriptableStream.close();
input.close();
//write the contents to the profile file
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
var stylesheetLink = childDoc.createElementNS(stylishCommon.HTMLNS, "link");
stylesheetLink.id = stylishCommon.getDOMId(uri);
stylesheetLink.type = "text/css";
stylesheetLink.rel = "stylesheet";
stylesheetLink.href = cssURL;
stylesheetLink.charset = "UTF-8";
//we can't use xml processing instructions because then they'd get put into the DOM and some code in the codebase assumes that no processing instructions are in the DOM <https://bugzilla.mozilla.org/show_bug.cgi?id=319654>. so let's use html:link and try to put it in an appropriate place
var nodeToAppendTo = null;
//XHTML head
var heads = childDoc.getElementsByTagNameNS(stylishCommon.HTMLNS, "head");
if (heads.length >= 1) {
nodeToAppendTo = heads[0];
}
if (!nodeToAppendTo) {
//HTML head
var heads = childDoc.getElementsByTagNameNS(null, "head");
if (heads.length >= 1) {
nodeToAppendTo = heads[0];
}
}
if (!nodeToAppendTo) {
//just jam it in the document element and hope for the best
nodeToAppendTo = childDoc.documentElement;
}
nodeToAppendTo.appendChild(stylesheetLink);
}
}
//Unregister code by stylish.rdf node uri
this.unregisterURI = function(uri) {
var node = this.ds.getNode(uri);
stylishCommon.unregisterNode(node);
}
//Unregister code by stylish.rdf node
this.unregisterNode = function(node) {
var uri = stylishCommon.getNodeURI(node);
var css = node.getTarget("urn:stylish#code").getValue();
var cssURL = stylishCommon.codePrefix + css;
var u = stylishCommon.ios.newURI(cssURL, null, null);
if (stylishCommon.sss.sheetRegistered(u, stylishCommon.sss.USER_SHEET)) {
//this can happen if someone's been fooling around with the rdf file since startup. Once Firefox is restarted, they'll be in sync again
dump("Stylish: Sheet not registered, so I can't unregister it.\n");
}
//instant unapply
//when we put the link code it, it strips whitespace, so to find a match we need to compare it to a the URL with no whitespace
var cssURLAttribute = cssURL.replace(/\n/, "");
var docs = this.getDocuments();
for (var i = 0; i < docs.length; i++) {
var childDoc = docs[i];
var link = childDoc.getElementById(stylishCommon.getDOMId(uri));
if (link) {
link.parentNode.removeChild(link);
}
}
}
//get the uri of the passed node
this.getNodeURI = function(node) {
return node.source.Value;
}
this.getDOMId = function(uri) {
return "stylish-" + uri.substring(6, uri.length)
}
//Returns an array of all open documents, whether chrome or content
this.getDocuments = function() {
var docs = [];
var ww = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
var windows = ww.getXULWindowEnumerator(null);
//For every window
while (windows.hasMoreElements()) {
//Get the window's main docshell
var windowDocShell = windows.getNext().QueryInterface(Components.interfaces.nsIXULWindow).docShell;
var containedDocShells = windowDocShell.getDocShellEnumerator(Components.interfaces.nsIDocShellTreeItem.typeAll, Components.interfaces.nsIDocShell.ENUMERATE_FORWARDS);
//For every docshell in the window
while (containedDocShells.hasMoreElements()) {
// Get the corresponding document for this docshell
var viewer = containedDocShells.getNext().QueryInterface(Components.interfaces.nsIDocShell).contentViewer;
// Adblock might block iframes/frames. Null check the content viewer.